﻿using System;
using System.Web.Mvc;
using System.Web.Routing;
using MugenInjection.Infrastructure;
using MugenInjection.Interface;

namespace MugenInjection.Web.Mvc
{
    /// <summary>
    ///     A controller factory that creates <see cref="IController" /> via Mugen injection.
    /// </summary>
    public class MugenInjectionControllerFactory : DefaultControllerFactory
    {
        #region Fields

        private readonly IInjector _injector;

        #endregion

        #region Constructors

        /// <summary>
        ///     Initializes a new instance of the <see cref="MugenInjectionControllerFactory" /> class.
        /// </summary>
        public MugenInjectionControllerFactory(IInjector injector)
        {
            Validate.ArgumentNotNull(injector, "injector");
            _injector = injector;
        }

        #endregion

        #region Override

        /// <summary>
        ///     Retrieves the controller instance for the specified request context and controller type.
        /// </summary>
        /// <returns>
        ///     The controller instance.
        /// </returns>
        /// <param name="requestContext">The context of the HTTP request, which includes the HTTP context and route data.</param>
        /// <param name="controllerType">The type of the controller.</param>
        /// <exception cref="T:System.Web.HttpException">
        ///     <paramref name="controllerType" /> is null.
        /// </exception>
        /// <exception cref="T:System.ArgumentException">
        ///     <paramref name="controllerType" /> cannot be assigned.
        /// </exception>
        /// <exception cref="T:System.InvalidOperationException">
        ///     An instance of <paramref name="controllerType" /> cannot be created.
        /// </exception>
        protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
        {
            if (controllerType == null)
                return base.GetControllerInstance(requestContext, null);
            object obj;
            IController controller = null;
            if (_injector.TryGet(controllerType, out obj))
                controller = obj as IController;
            return controller ?? base.GetControllerInstance(requestContext, controllerType);
        }

        #endregion
    }
}